iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Modern Web

重造會 Slide 的輪子!深入 JavaScript、CSS 模組化設計系列 第 19

Day 19 - CSS Coding Style: BEM 命名模式

  • 分享至 

  • xImage
  •  

你或許已經有聽過用在 CSS 上的一種程式碼風格 - BEM 命名模式,甚至已經開始始用。如果沒聽過,或還沒開始始用,或許可以一起來瞭解一下,這種「已經」在各種知名、流行的 JavaScript 前端套件廣泛使用的 CSS 編寫風格。

BEM

BEM 是什麼意思呢?這個縮寫代表以下三種

  • B:區塊 (block)。
  • E:元素 (element)。
  • M:修飾子 (modifier)。

對於 CSS 的 class 名稱命名的方式為:

  • 使用 class,不使用 id。
  • 區塊和元素使用兩個「_」下底線 (underscore) 連接,元素和修飾子之間使用兩個「」連字號 (hyphen) 連接。
  • 區塊、元素、修飾子的名稱,字詞語字詞間用一個連字號連接。

區塊 (block)

最重要的是要有獨立功用的意思。例如選單 (menu)、頁首 (page header)、頁尾 (page footer)、文章主體 (article body) 諸如此類,就是一種區塊的概念。

IT 邦幫忙個人資料頁首區塊
圖 a: IT 邦幫忙個人資料頁首區塊

IT 邦幫忙網站也是採用 BEM 命名模式喔!
例如筆者的 IT 邦幫忙的個人檔案頁,在上方個人資料區塊,樣式名稱為 profile-header,就是一種區塊。

元素 (element)

查看 DOM 元素的範圍及尺寸
圖 b: 查看 DOM 元素的範圍及尺寸

包含在區塊內,沒有獨立的意義,但和區塊有高度關聯性,例如:

  • profile-header__content:包裝內文的容器。
  • profile-header__avatar:筆者的照騙。
  • profile-header__name:筆者的筆名 TerrL. (terrylinooo)
  • profile-header__text:iT邦新手 2 級 ‧ 點數 1104、全端帥大叔

修飾子 (modifier)

用來代表元素的狀態、顏色、動作、等等。

查看網頁原始碼
圖 c: 查看網頁原始碼

以 IT 邦幫忙的設計來說:

  • profile-nav 是個人檔案導覽區塊
  • profile-nav__item 是個人檔案導覽區塊的每一個項目。
  • profile-nav__item--pad 代表在手機版本狀態時,增加手機版導覽的下拉選單。


圖 d: 修飾子範例位置

是不是很方便又易讀?

語法

.block-name__element-name--modifier-name

看起來樣式名稱又長又醜,這通常是一開始接觸的第一印像。

優點

坦白說,筆者剛開始使用的時候也非常不習慣,但用了幾個小時候就體悟到 BEM 帶來的好處。

首先,第一個好處就是構思樣式名稱的時間會大幅減低。

打個比方,使用 Bootstrap、Semantic UI 等前端 CSS 框架,或者下載現成的網頁 template,都已經有大量通俗名稱的 CSS 樣式名稱被定義。採用這些現成的 CSS 作品作為開發材料,就必須思考不與這些材料產生衝突的樣式名稱。

如果自己命名像是 .container.menu-item.section-title 等等,常會有不預期的結果。

第二個值得讚賞的地方,樣式名稱可以看出區塊關聯性。在修改樣式時,子元素帶有和父元素的區塊名稱,直覺地可以看出區塊之間的關聯性,這也幫助了維護的效率。

缺點

有優點,當然也會有缺點。就是樣式名稱太長。
但在「SCSS」工具的幫助下,用 SCSS 來編寫 CSS 語法,這個缺點就不存在了。

範例 (HTML)

<div class="header-menu">
  <div class="header-menu__item header-menu__item--active">選單已選</div>
  <div class="header-menu__item">選單名稱</div>
</div>

範例 (SCSS)

.header-menu {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;

  &__item {
    height: 30px;
	line-height: 30px;

    &--active {
      font-weight: bold;
    }
  }
}

透過 SCSS 轉譯工具,為幫我們從上面的清爽語法,轉成 BEM 風格的 CSS 語法。

總結

採用 BEM 命名模式,要和其它框架或套件撞名,大概比中統一發票兩百元的機率還低。
既然我們要設計一個開發讓大家使用的套件,在樣式名稱的設計上,自然不能被使用者的網站影響,也不要去影響使用者的網頁現有樣式。

接下來的套件設計都會開始使用 SCSS + BEM 的組合囉!
明天 Day 20,要介紹 JavaScript 模組化標準 ESM,把程式碼模組化的方法。


今天的文章沒有實體網站範例,不過之前的範例可在 GitHub Page 閱讀。
原始碼可在 2022 鐵人賽專用 GitHub Repo 下載。


上一篇
Day 18 - CSS 漸變動畫屬性 (Transition)
下一篇
Day 20 - JavaScript 模組化標準 ESM
系列文
重造會 Slide 的輪子!深入 JavaScript、CSS 模組化設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言